﻿#pragma once
#include <QObject>
#include <QImage>
#include <QThread>
#include <opencv2/opencv.hpp>
#include <qmap>
#include <deque>
//#include "IInfer.h"
//#include "LCCGLApi.h"
#include "Visionapi.h"

#include "HalconCpp.h"
#include "HShapeModel.h"
using namespace HalconCpp;
// 业务逻辑层：用于处理检测逻辑

// 匹配结果
typedef struct tagMatchResult
{
    double x;
    double y;
    double score;
    double rotAngle;
    double sx;
    double sy;
    int modelId;

    // 机器人坐标系坐标
    double rx;
    double ry;

    int index;
}MatchResult;

// 定义采集图像列表：用Deque容器，可以进行双向操作，先入先出
using GrabImageList = std::deque<cv::Mat>;
using MatchResults = std::vector<MatchResult>;

class Calibration_NinePoint;
class VisionMainWnd;
class IInfer;
class CSQLData;
class DataProducer;
using namespace VisionApi;
class InspectLL :
    public QObject
{
    Q_OBJECT
public:
    InspectLL();
    ~InspectLL();

    void setMainWin(VisionMainWnd* mainWin) { mainWin_ = mainWin; };
    // 将图像采集备份到处理队列
    void grabImage(cv::Mat& img);
    // 主要处理接口：推理+结果图形绘制
    void inspect(cv::Mat &src);

    bool isFinished() { return proFinished_; }
    void setFinished(bool finish) { proFinished_ = finish; }
    bool isFindObj() { return findObj_; }
    void setFindObj(bool find) { findObj_ = find; }
    void addObjCount() { objGrabCount_++; }
    void resetObjCount() { objGrabCount_ = 0; }
    long getObjCount() { return objGrabCount_; }

    int getMatchCount() {
        return matchCount_;
    }
    void resetMatchCount() { matchCount_ = 0; }

    cv::Point2d getImageXY();
    cv::Point2d getRobotXY();
    Calibration_NinePoint* getCalibObj() { return calibration_; }
    
    // 设置ROI接口
    void setRoiRect(cv::Rect roi) { searchRoi_ = roi; }
    cv::Rect getRoiRect() { return searchRoi_; }
    // 绘制roi接口
    void setRoiVisible(bool visible) { roiVisible_ = visible; }
    bool isRoiVisible() { return roiVisible_; }

    void setSaveSrcImage(bool save) { saveSrcImage_ = save; }
    bool isSaveSrcImage() {  return saveSrcImage_;    }

    void saveRoi();


    void init();

    void loadModel();
    void loadConfig(); // 加载指定料号:参数位指定路径目录，每个目录下存放相关模板信息
    void loadModel(QString dirPN);   // 加载指定料号目录
    void setCurrentPn(QString pn) { lastPn_ = pn; }
    QString getCurPN() { return lastPn_; }
    void saveModelInfo();      // 写模板信息
    cv::Mat& getModelResult() { return modelResult_; }

    MatchResult* findBestResult();              // 匹配分数最高的最优
    MatchResult* findBestResult_farPriority();  // 最远的优先，选为最优
    MatchResult* getBestResult() { return bestResult_; }
    MatchResults* getAllResult() { return &allResults_; }

    void setEnableInsp(bool enable) { enableInsp_ = enable; }
    bool isEnableInsp() { return enableInsp_; }

    double getInspTime() { return inspectTime_; }

    void setDrawAllResult(bool draw) { drawAllResult_ = draw; }
    bool isDrawAllResult() { return drawAllResult_; }    

signals:
    void update_ui(std::string, std::string, double, double, double);
    void send_pro_info(double, int);
    void send_info_show();
    void send_image_show(cv::Mat, bool save);

protected:
    // 初始化读取配置参数
    void readParams();
    void readCalibParams();
    // 主线程：循环处理图像队列
    void loopProcess();

    bool findMaxMatchIndex(HTuple &scores);

    // 绘制目标轮廓
    void drawResult(cv::Mat &src, std::vector<polygonPoints>& allContours);

    HImage preProcess(HImage& src);   

    // 简单分割
    HRegion easySegmentObject(HImage src, double lowThres, double highThres);


    void drawAllResult(cv::Mat &src);
    void drawResultsRect2(cv::Mat& src);

private:
    VisionMainWnd* mainWin_ = nullptr;
    //IInfer* infer_objDetect_ = nullptr;

    bool proFinished_ = true;
    bool enableInsp_ = false;
    QString shapeModelFile_ = "";
    HShapeModelArray mulShapeModel_;    // 模板数组
    HTuple mulShapeModels_;
    std::vector<RotRect> modelContourRect2_;    // 模板的外接矩形
    HRegion matchRoi_;                  // 匹配ROI区域
    int matchCount_ = 0;                // 匹配到的数目
    bool drawAllResult_ = false;

    long objGrabCount_ = 0; // 抓取目标数目统计
    bool findObj_ = false;
    MatchResults allResults_;
    MatchResult* bestResult_ = nullptr;

    Calibration_NinePoint* calibration_ = nullptr;

    HTuple scaledShapeModels_;
    cv::Rect searchRoi_;
    bool roiVisible_ = false;
    cv::Scalar roiColor_ = cv::Scalar(0, 255, 0);

    double inspectTime_ = 0.0;

    int indexOfMaxScore_ = -1;
    double matchMaxScore_ = 0;

    QString lastPn_;    // 最后生产的料号，默认启动时加载

    bool saveSrcImage_ = false;
    cv::Mat modelResult_;
    std::vector<polygonPoints> allContours_;
};
